package com.milepost.workflow.attach.service.impl;

import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.milepost.workflow.attach.entity.FlowAttachEntity;
import com.milepost.workflow.attach.mapper.FlowAttachMapper;
import com.milepost.workflow.attach.service.FlowAttachService;
import com.milepost.workflow.common.enums.TaskTypeEnum;
import com.milepost.workflow.flowinsttask.entity.FlowInstTaskEntity;
import com.milepost.workflow.flowinsttask.mapper.FlowInstTaskMapper;
import com.milepost.workflow.util.UUIDUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Date;
import java.util.List;

/**
 * @author huarf
 * @Description
 * @create 2022-04-04 21:13
 */
@Service
@RequiredArgsConstructor
@Transactional(rollbackFor = Exception.class)
public class FlowAttachServiceImpl extends ServiceImpl<FlowAttachMapper, FlowAttachEntity> implements FlowAttachService {

    @Value("${attach.position}")
    private String attachPosition;

    private final FlowInstTaskMapper flowInstTaskMapper;

    @Override
    public boolean upload(List<MultipartFile> multipartFileList, FlowAttachEntity flowAttachEntity) throws Exception {

        if (StringUtils.isNotBlank(flowAttachEntity.getFlowInstId())
                && StringUtils.isBlank(flowAttachEntity.getFlowInstTaskAppId())) {
            //发起流程时上传附件，获取开始节点id
            FlowInstTaskEntity startTask = flowInstTaskMapper.selectOne(new QueryWrapper<FlowInstTaskEntity>()
                    .lambda().eq(FlowInstTaskEntity::getFlowInstId, flowAttachEntity.getFlowInstId())
                    .eq(FlowInstTaskEntity::getType, TaskTypeEnum.START.getType()));
            flowAttachEntity.setFlowInstTaskId(startTask.getId());
        }

        Date nowDate = new Date();
        flowAttachEntity.setCrtTime(nowDate);
        flowAttachEntity.setPath(DateFormatUtils.format(nowDate, "yyyyMMdd"));

        //保存文件和数据
        for (int i = 0; i < multipartFileList.size(); i++) {
            MultipartFile multipartFile = multipartFileList.get(i);

            InputStream inputStream = null;
            OutputStream tempOutputStream = null;
            InputStream hashInputStream = null;
            OutputStream saveFileOutputStream = null;
            InputStream saveFileinputStream = null;
            File tempFile = null;

            try {

                //文件再试存储到本地
                inputStream = multipartFile.getInputStream();
                tempFile = File.createTempFile("workflow", ".tmp");
                tempOutputStream = new FileOutputStream(tempFile);
                FileCopyUtils.copy(inputStream, tempOutputStream);

                //构建数据
                FlowAttachEntity flowAttachEntityItem = new FlowAttachEntity();
                BeanUtils.copyProperties(flowAttachEntity, flowAttachEntityItem);
                flowAttachEntityItem.setId(UUIDUtil.randomUUID());

                String originalFilename = multipartFile.getOriginalFilename();
                String name = originalFilename.split("\\.")[0];
                String ext = originalFilename.split("\\.")[1];
                flowAttachEntityItem.setName(name);
                flowAttachEntityItem.setExt(ext);
                flowAttachEntityItem.setSize(multipartFile.getSize());
                flowAttachEntityItem.setContentType(multipartFile.getContentType());
                hashInputStream = new FileInputStream(tempFile);
                flowAttachEntityItem.setHash(DigestUtils.md5DigestAsHex(hashInputStream));
                flowAttachEntityItem.setOrderNum(i + 1);

                String filePosition = attachPosition + File.separator + flowAttachEntityItem.getPath();
                File filePositionFile = new File(filePosition);
                if (!filePositionFile.exists()) {
                    filePositionFile.mkdirs();
                }

                //保存文件
                File outFile = new File(filePosition + File.separator + flowAttachEntityItem.getHash() + "." + flowAttachEntityItem.getExt());
                saveFileOutputStream = new FileOutputStream(outFile);
                saveFileinputStream = new FileInputStream(tempFile);
                int bytesCopied = FileCopyUtils.copy(saveFileinputStream, saveFileOutputStream);

                //保存数据
                int insert = baseMapper.insert(flowAttachEntityItem);
                if (insert <= 0) {
                    throw new RuntimeException("保存附件数据失败");
                }
            } finally {
                IoUtil.close(saveFileinputStream);
                IoUtil.close(saveFileOutputStream);
                IoUtil.close(hashInputStream);
                IoUtil.close(tempOutputStream);
                IoUtil.close(inputStream);
                if (tempFile != null && tempFile.isFile()) {
                    tempFile.delete();
                }
            }
        }

        return true;
    }
}
